package com.plugin;

import com.util.StringUtil;
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.GeneratedXmlFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.codegen.XmlConstants;
import org.mybatis.generator.config.PropertyRegistry;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 描述：生成ext扩展代码代码
 * 作者：刘飞华
 * 日期：2024/7/24 13:46
 */
public class ExtGenerator extends PluginAdapter {

    private final Properties properties;

    private String author;

    private String createTime;

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    public ExtGenerator() {
        this.properties = new Properties();
    }

    public ExtGenerator(Properties properties) {
        this.properties = properties;

    }

    @Override
    public void setProperties(Properties properties) {
        this.properties.putAll(properties);
        this.author = properties.getProperty("author");
        SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        this.createTime = dateFormatter.format(new Date());
    }

    /**
     * 可以生成自定义的文件
     */
    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        List<GeneratedJavaFile> javaFiles = new ArrayList<>();
        javaFiles.add(genExtEntityJavaFile(introspectedTable));
        javaFiles.add(genExtDaoJavaFile(introspectedTable));
//        javaFiles.add(genExtMapperJavaFile(introspectedTable));


        return javaFiles;
    }

    /**
     * 可以生成自定义的文件
     */
    @Override
    public List<GeneratedXmlFile> contextGenerateAdditionalXmlFiles(IntrospectedTable introspectedTable) {
        List<GeneratedXmlFile> xmlFiles = new ArrayList<>();
        xmlFiles.add(genExtMapperJavaFile(introspectedTable));


        return xmlFiles;
    }


    /**
     * 生成一个自定义文件
     */
    private GeneratedJavaFile genExtEntityJavaFile(IntrospectedTable introspectedTable) {
        String targetPackage = properties.getProperty("targetPackage");
        String[] split = introspectedTable.getBaseRecordType().split("\\.");
        String modelName = split[split.length - 1];
        String typeName = targetPackage + ".entity.ext." + modelName + "Ext";
        //类的完全限定名（决定生成的文件的目录接口）
        TopLevelClass c = new TopLevelClass(typeName);

        //设置注释
        c.addJavaDocLine("/**");
        String remarks = introspectedTable.getRemarks().replace("表", "");
        c.addJavaDocLine(" * 描述: " + remarks);
        c.addJavaDocLine(" * 作者: " + author);
        c.addJavaDocLine(" * 日期: " + createTime);
        c.addJavaDocLine(" */");

        c.addJavaDocLine("@Data");
        c.addJavaDocLine("@Builder");

        c.setVisibility(JavaVisibility.PUBLIC);

        c.addSuperInterface(new FullyQualifiedJavaType("Serializable"));
        //导入的依赖包
        c.addImportedType(new FullyQualifiedJavaType("java.io.Serializable"));
        c.addImportedType(new FullyQualifiedJavaType("lombok.*"));

        //构建一个编译单元
        GeneratedJavaFile generatedJavaFile = new GeneratedJavaFile(
                c,
                context.getJavaModelGeneratorConfiguration().getTargetProject(),
                context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                context.getJavaFormatter());

        return generatedJavaFile;
    }

    /**
     * 生成一个自定义文件
     */
    private GeneratedJavaFile genExtDaoJavaFile(IntrospectedTable introspectedTable) {
        String targetPackage = properties.getProperty("targetPackage");
        String[] split = introspectedTable.getBaseRecordType().split("\\.");
        String modelName = split[split.length - 1];
        String typeName = targetPackage + ".dao.ext." + modelName + "DaoExt";
        //类的完全限定名（决定生成的文件的目录接口）
        Interface c = new Interface(typeName);

        //设置注释
        c.addJavaDocLine("/**");
        String remarks = introspectedTable.getRemarks().replace("表", "");
        c.addJavaDocLine(" * 描述: " + remarks);
        c.addJavaDocLine(" * 作者: " + author);
        c.addJavaDocLine(" * 日期: " + createTime);
        c.addJavaDocLine(" */");

        c.setVisibility(JavaVisibility.PUBLIC);

        // 添加Mapper的注解
        c.addAnnotation("@Mapper");


        c.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));

        //构建一个编译单元
        GeneratedJavaFile generatedJavaFile = new GeneratedJavaFile(
                c,
                context.getJavaModelGeneratorConfiguration().getTargetProject(),
                context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                context.getJavaFormatter());

        return generatedJavaFile;
    }

    /**
     * 生成一个自定义文件
     */
    private GeneratedXmlFile genExtMapperJavaFile(IntrospectedTable introspectedTable) {
        String targetPackage = properties.getProperty("targetPackage");
        String xmlPackage = properties.getProperty("xmlPackage");
        String[] split = introspectedTable.getBaseRecordType().split("\\.");
        String modelName = split[split.length - 1] + "DaoExt.xml";
        Document document = new Document(
                XmlConstants.MYBATIS3_MAPPER_PUBLIC_ID,
                XmlConstants.MYBATIS3_MAPPER_SYSTEM_ID
        );

        XmlElement root = new XmlElement("mapper");
        document.setRootElement(root);
        String v = targetPackage + ".dao.ext." + modelName.replace(".xml","");
        root.addAttribute(new Attribute("namespace", v));

        root.addElement(new TextElement("<!--"));
        root.addElement(new TextElement("  This file is generated by MyBatis Generator."));
        String s = "  This file was generated on " + new Date() + '.';
        root.addElement(new TextElement(s));

        root.addElement(new TextElement("-->\n"));

        root.addElement(new TextElement("<!--"));
        root.addElement(new TextElement("<insert id=\"insertId\" parameterType=\"java.lang.Long\">"));
        root.addElement(new TextElement("在这里扩展添加"));
        root.addElement(new TextElement("</insert>"));
        root.addElement(new TextElement("-->\n"));

        root.addElement(new TextElement("<!--"));
        root.addElement(new TextElement("<delete id=\"deleteId\" parameterType=\"java.lang.Long\""));
        root.addElement(new TextElement("在这里扩展删除"));
        root.addElement(new TextElement("</delete>"));
        root.addElement(new TextElement("-->\n"));

        root.addElement(new TextElement("<!--"));
        root.addElement(new TextElement("<update id=\"updateId\" parameterType=\"java.lang.Long\">"));
        root.addElement(new TextElement("//在这里扩展修改"));
        root.addElement(new TextElement("</update>"));
        root.addElement(new TextElement("-->\n"));

        root.addElement(new TextElement("<!--"));
        root.addElement(new TextElement("<update id=\"updateStatus\" parameterType=\"java.lang.Long\">"));
        root.addElement(new TextElement("//在这里扩展修改状态"));
        root.addElement(new TextElement("</update>"));
        root.addElement(new TextElement("-->\n"));

        root.addElement(new TextElement("<!--"));
        root.addElement(new TextElement("<select id=\"selectId\" parameterType=\"java.lang.Long\" resultType=\"java.lang.Long\">"));
        root.addElement(new TextElement("//在这里扩展查询详情"));
        root.addElement(new TextElement("</select>"));
        root.addElement(new TextElement("-->\n"));

        root.addElement(new TextElement("<!--"));
        root.addElement(new TextElement("<select id=\"selectList\" parameterType=\"java.lang.Long\" resultType=\"java.lang.Long\">"));
        root.addElement(new TextElement("//在这里扩展查询列表"));
        root.addElement(new TextElement("</select>"));
        root.addElement(new TextElement("-->\n"));


        return new GeneratedXmlFile(document, modelName, xmlPackage, "src/main/resources", false, context.getXmlFormatter());
    }


}
